package com.benyanyi.permissionlib;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.benyanyi.loglib.Jlog;
import com.benyanyi.permissionlib.callback.PermissionCallBack;
import com.benyanyi.permissionlib.dialog.PermissionDialogInfo;
import com.benyanyi.permissionlib.shortcut.RuntimeSettingPage;
import com.benyanyi.permissionlib.shortcut.ShortcutPermissionChecker;
import com.benyanyi.permissionlib.type.PermissionType;

import java.util.ArrayList;
import java.util.List;

/**
 * @author YanYi
 * @date 2019/5/23 11:02
 * @email ben@yanyi.red
 * @overview
 */
public final class PermissionFragment extends Fragment {

    private PermissionDialogInfo info;
    private final int code1 = 0x31;
    private final int code2 = 0x32;
    private boolean isStop = false;
    private boolean isShow = false;

    private List<String> oList = new ArrayList<>();

    private String[] permissions;
    private PermissionCallBack callBack;

    private boolean manageExternalStorage = false;
    private boolean shortcutPermission = false;

    private boolean checkManageExternalStorage = false;//判断是否请求访问全部文件权限
    private boolean checkShortcutPermission = false;//判断是否请求创建快捷方式权限

    private static final String MARK = Build.MANUFACTURER.toLowerCase();

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        this.isStop = false;
    }

    /**
     * 设置权限
     */
    void setPermissions(String[] permissions) {
        List<String> list1 = new ArrayList<>();
        for (String permission : permissions) {
            if (permission.equalsIgnoreCase(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    manageExternalStorage = true;
                }
            } else if (permission.equalsIgnoreCase(PermissionType.SHORTCUT)) {
                shortcutPermission = true;
            } else {
                list1.add(permission);
            }
        }
        this.permissions = list1.toArray(new String[0]);
    }

    /**
     * 设置弹窗
     */
    void setInfo(PermissionDialogInfo info) {
        this.info = info;
        if (this.info != null && this.info.isShow) {
            this.isShow = true;
        }
    }

    /**
     * 设置回调
     */
    void setCallBack(PermissionCallBack callBack) {
        this.callBack = callBack;
    }

    /**
     * 开始请求权限
     */
    void startForPermissionResult() {
        if (checkPermission()) {
            if (!manageExternalStorage && !shortcutPermission) {
                if (this.callBack != null) {
                    this.callBack.onSuccess();
                    this.callBack.onComplete();
                    PermissionHelper.removeFragment();
                }
            } else {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && manageExternalStorage && !Environment.isExternalStorageManager()) {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                    startActivity(intent);
                } else if (shortcutPermission && !checkShortcut()) {
                    RuntimeSettingPage settingPage = new RuntimeSettingPage(getActivity());
                    settingPage.start();
                } else {
                    if (this.callBack != null) {
                        this.callBack.onSuccess();
                        this.callBack.onComplete();
                        PermissionHelper.removeFragment();
                    }
                }
            }
        } else {
            requestPermission(code1);
        }
    }

    /**
     * 判断权限是否拥有
     *
     * @return 权限是否获取（获取true）
     */
    private boolean checkPermission() {
        oList.clear();
        if (permissions == null || permissions.length == 0) {
            return true;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for (String permission : permissions) {
                if (!permission.equalsIgnoreCase(PermissionType.SHORTCUT) && ContextCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED) {
                    if (!oList.contains(permission)) {
                        oList.add(permission);
                    }
                }
            }
        } else {
            for (String permission : permissions) {
                if (!permission.equalsIgnoreCase(PermissionType.SHORTCUT) && ActivityCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED) {
                    if (!oList.contains(permission)) {
                        oList.add(permission);
                    }
                }
            }
        }
        return oList.isEmpty();
    }

    /**
     * 判断是否有创建快捷方式权限
     *
     * @return 是否有创建快捷方式权限
     */
    private boolean checkShortcut() {
        Jlog.v(MARK);
        boolean result = false;
        if (MARK.contains("huawei")) {
            result = ShortcutPermissionChecker.checkOnEMUI(getActivity());
        } else if (MARK.contains("xiaomi")) {
            result = ShortcutPermissionChecker.checkOnMIUI(getActivity());
        } else if (MARK.contains("oppo")) {
            result = ShortcutPermissionChecker.checkOnOPPO(getActivity());
        } else if (MARK.contains("vivo")) {
            result = ShortcutPermissionChecker.checkOnVIVO(getActivity());
        } else if (MARK.contains("samsung") || MARK.contains("meizu")) {
            result = true;
        }
        return !result;
    }

    /**
     * 请求权限
     */
    @TargetApi(Build.VERSION_CODES.M)
    private void requestPermission(int code) {
        requestPermissions(permissions, code);
    }

    /**
     * 权限请求拒绝后弹窗
     * Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
     * intent.setData(Uri.parse("package:" + getActivity().getPackageName()));
     * getActivity().startActivityForResult(intent, requestCode);
     */
    private void showDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        String title = info == null ? "权限不足" : (TextUtils.isEmpty(info.title) ? "权限不足" : info.title);
        String message = info == null ? "需要必须的权限才能正常使用本应用" :
                (TextUtils.isEmpty(info.message) ? "需要必须的权限才能正常使用本应用" : info.message);
        String positiveText = info == null ? "重新获取权限" : (TextUtils.isEmpty(info.positiveText) ? "重新获取权限" : info.positiveText);
        String negativeText = info == null ? "退出" : (TextUtils.isEmpty(info.negativeText) ? "退出" : info.negativeText);
        boolean isShow;
        if (info == null) {
            isShow = false;
        } else {
            isShow = info.isShow;
        }
        final PermissionDialogInfo.NegativeClick negativeClick = info == null ? null : info.negativeClick;
        final PermissionDialogInfo.PositiveClick positiveClick = info == null ? null : info.positiveClick;
        builder.setTitle(title);
        builder.setMessage(message);
        builder.setCancelable(false);
        builder.setPositiveButton(positiveText, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                if (positiveClick != null) {
                    positiveClick.onClick(callBack, PermissionFragment.this.oList.toArray(new String[0]));
                } else {
                    requestPermission(code2);
                }
            }
        });
        builder.setNegativeButton(negativeText, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                if (negativeClick != null) {
                    negativeClick.onClick(callBack, PermissionFragment.this.oList.toArray(new String[0]));
                } else {
                    if (callBack != null) {
                        callBack.onFailure(PermissionFragment.this.oList.toArray(new String[0]));
                        callBack.onComplete();
                        PermissionHelper.removeFragment();
                    }
                }
            }
        });
        if (isShow) {
            builder.show();
        } else {
            setFailure();
        }
        this.isShow = false;
    }

    /**
     * 权限请求后回调
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Jlog.d();
        List<String> list = hasAllPermissionsGranted(permissions, grantResults);
        boolean boo = list.isEmpty() && (this.code1 == requestCode || this.code2 == requestCode);
        if (boo) {
            if (manageExternalStorage || shortcutPermission) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && manageExternalStorage && !Environment.isExternalStorageManager()) {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                    startActivity(intent);
                } else if (shortcutPermission && !checkShortcut()) {
                    RuntimeSettingPage settingPage = new RuntimeSettingPage(getActivity());
                    settingPage.start();
                } else {
                    if (this.callBack != null) {
                        this.callBack.onSuccess();
                        this.callBack.onComplete();
                        PermissionHelper.removeFragment();
                    }
                }
            } else {
                if (this.callBack != null) {
                    this.callBack.onSuccess();
                    this.callBack.onComplete();
                    PermissionHelper.removeFragment();
                }
            }
        } else if (manageExternalStorage && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
                && !Environment.isExternalStorageManager()) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
            startActivity(intent);
        } else if (shortcutPermission && !checkShortcut()) {
            RuntimeSettingPage settingPage = new RuntimeSettingPage(getActivity());
            settingPage.start();
        } else {
            oList = list;
            if (this.code1 == requestCode) {
                boolean isShow;
                if (info == null) {
                    isShow = false;
                } else {
                    isShow = info.isShow;
                }
                if (isShow) {
                    showDialog();
                } else {
                    setFailure();
                }
            } else if (this.code2 == requestCode) {
                setFailure();
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        int requestCode1 = 0x33;
        if (requestCode1 == requestCode) {
            requestPermission(this.code2);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        Jlog.d("onResume：" + isStop);
        if (this.isStop) {
            if (checkPermission()) {
                Jlog.v();
                if (manageExternalStorage || shortcutPermission) {
                    Jlog.d(manageExternalStorage);
                    Jlog.d(checkManageExternalStorage);
                    Jlog.d(shortcutPermission);
                    Jlog.d(checkShortcutPermission);
                    List<String> list = new ArrayList<>();
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && manageExternalStorage && !Environment.isExternalStorageManager()) {
                        if (!checkManageExternalStorage) {
                            Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                            startActivity(intent);
                            checkManageExternalStorage = true;
                        } else {
                            Jlog.d();
                            list.add(Manifest.permission.MANAGE_EXTERNAL_STORAGE);
                        }
                    }
                    if (shortcutPermission && !checkShortcut()) {
                        Jlog.d(checkShortcutPermission);
                        if (!checkShortcutPermission) {
                            RuntimeSettingPage settingPage = new RuntimeSettingPage(getActivity());
                            settingPage.start();
                        } else {
                            list.add(PermissionType.SHORTCUT);
                        }
                    }
                    Jlog.d(list.size());
                    if (!list.isEmpty()) {
                        if (this.callBack != null) {
                            this.callBack.onFailure(list.toArray(new String[0]));
                            this.callBack.onComplete();
                            PermissionHelper.removeFragment();
                        }
                    } else {
                        if (this.callBack != null) {
                            this.callBack.onSuccess();
                            this.callBack.onComplete();
                            PermissionHelper.removeFragment();
                        }
                    }
                } else {
                    if (this.callBack != null) {
                        this.callBack.onSuccess();
                        this.callBack.onComplete();
                        PermissionHelper.removeFragment();
                    }
                }
            } else {
                Jlog.d(manageExternalStorage);
                Jlog.d(checkManageExternalStorage);
                Jlog.d(shortcutPermission);
                Jlog.d(checkShortcutPermission);
                List<String> list = new ArrayList<>();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && manageExternalStorage && !Environment.isExternalStorageManager()) {
                    if (!checkManageExternalStorage) {
                        Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                        startActivity(intent);
                        checkManageExternalStorage = true;
                    } else {
                        Jlog.d();
                        list.add(Manifest.permission.MANAGE_EXTERNAL_STORAGE);
                    }
                }
                if (shortcutPermission && !checkShortcut()) {
                    Jlog.d(checkShortcutPermission);
                    if (!checkShortcutPermission) {
                        RuntimeSettingPage settingPage = new RuntimeSettingPage(getActivity());
                        settingPage.start();
                    } else {
                        list.add(PermissionType.SHORTCUT);
                    }
                }
                if (this.isShow) {
                    showDialog();
                } else if (this.callBack != null) {
                    oList.addAll(list);
                    this.callBack.onFailure(this.oList.toArray(new String[0]));
                    this.callBack.onComplete();
                    PermissionHelper.removeFragment();
                }

            }
        }
        this.isStop = false;
    }

    @Override
    public void onStop() {
        super.onStop();
        this.isStop = true;
        Jlog.d("onStop");
    }

    private void setFailure() {
        if (this.callBack != null) {
            this.callBack.onFailure(this.oList.toArray(new String[0]));
            this.callBack.onComplete();
            PermissionHelper.removeFragment();
        }
    }

    private List<String> hasAllPermissionsGranted(String[] permissions, int[] grantResults) {
        List<String> list = new ArrayList<>();
        if (grantResults.length <= 0) {
            return list;
        }
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                list.add(permissions[i]);
            }
        }
        return list;
    }
}
